<html>

<head>
<meta http-equiv="Content-Language" content="en-au">
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>FileDb Overview</title>
</head>

<body>

<b>
<p><font face="Arial" size="4" color="#0066CC">Overview</font></p>
</b>
<p><font face="Arial">FileDb is a simple database designed as a simple 
local database solution for Xamarin Cross-Platform phone (Android, IOS, WinPhone) 
or any .NET application.&nbsp; <u>FileDb is a No-SQL database</u> 
						meant for use as a local data store for applications.&nbsp; 
						Here are some important points about FileDb:</font></p>
                    
                      <ul>
						<li>
                    	<font face="Arial">Stores one table per file, including its index</font></li>
                        <li>
                    	<font face="Arial">Extremely Lightweight - less than 50K</font></li>
						<li>
                    	<font face="Arial">Supports field types Int, UInt, Bool, String, Byte, 
						Float, Double and DateTime and also arrays of the same 
						types</font></li>
						<li>
                    	<font face="Arial">Index supports a single Primary Key field (optional)</font></li>
                        <li>
                        <font face="Arial">Compiled versions for Windows Phone 
						RT/PCL,  
						.NET</font></li>
						<li>
                        <font face="Arial">FileDb is VERY FAST</font></li>
                        <li>
                    	<font face="Arial">FileDb is FREE to use in your applications</font></li>
						<li>
                    	<font face="Arial">Use with LINQ to Objects to achieve full relational 
						capability</font></li>
                      </ul>

						<p><font face="Arial">FileDb was specifically designed to use only native 
						.NET data types so there would no need to translate 
						between database storage and the CLR data types.&nbsp; 
						So you can just as easily read/write a String[] field as 
						you would an Int field.&nbsp; Another feature is that a 
						database file created on any .NET platform will work on 
						any other.&nbsp; So you can create a database file on 
						your Windows machine and it can be used in a Silverlight 
						or Windows Phone app.</font></p>

						<p><font color="#0066CC" face="Arial"><b>LINQ + FileDb gives you full 
						relational database capability</b></font></p>
						<p><font face="Arial">Even though FileDb is a &quot;flat-file&quot; database, using 
						LINQ it becomes fully relational!&nbsp; LINQ 
						to Objects allows you to join Tables together just as 
						you would do in SQL. All of the power of LINQ is 
						available to you: Joins, Grouping, Sum - the lot.&nbsp; 
						(See 
						the examples below.)</font></p>
						<p><font face="Arial">FileDb also has a built-in 
						query filter parser so you can write SQL-like 
						filter expressions to make filtering data easy, like 
						this:</font></p>
						<blockquote>
							<p><b>
							<font color="#663300" face="Courier New" size="2">
							string filter = &quot;FirstName IN (&#39;Cindy&#39;, &#39;John&#39;) AND Age &gt; 32&quot;</font></b></p>
						</blockquote>
						<p><font face="Arial">Use FileDb in your .NET and mobile 
						applications where you need a searchable, updatable 
						local database.</font><p>
<b><font face="Arial" color="#0066CC">Use FileDb with Xamarin cross-platform app 
development</font></b><p><font face="Arial">Most phone apps only require a 
simple database.&nbsp; By purchasing a source code license you can compile 
FileDb into your IOS, Android and Windows Phone projects and use the same exact 
data layer code for them all.&nbsp; This is much easier than using Sqlite 
wrappers.&nbsp; With FileDb's built in encryption you can have everything you 
need to have a secure data layer.</font></p>
						<p>
<font color="#0066CC" face="Arial"><b>FileDb Database Overview</b></font></p>

<p><font face="Arial">FileDb is a simple database designed for use on any .NET platform such as Windows 
Phone and Silverlight, but its also great for any .NET app where simple local 
database storage is needed. For example, instead of using XML config files you 
could use a FileDb database to store and retrieve application data much more 
efficiently. FileDb allows only a single table per database file, so when we 
talk about a FileDb database we really mean a single table with an index. The 
index is stored in the file with the data, and allows an optional Primary Key.</font></p>
<p><font face="Arial">FileDb is NOT a relational database - it is NO-SLQ, 
meaning you can't directly issue SQL commands for querying, adding or updating. However, 
you CAN use LINQ with 
FileDb to get full relational query capabilities.&nbsp;&nbsp; And FileDb does include an Expression Parser which parses SQL-like filter 
expressions, which makes searching, updating and deleting very easy - see below for an example.</font></p>
<p><font face="Arial"><u>And FileDb supports using powerful Regular Expressions for 
filtering.</u></font></p>
<p><font face="Arial"><u>FileDb supports AES encryption</u> at the record level. This 
means the database schema is not encrypted (field names, etc.), but each record 
is entirely encrypted. Encryption is &quot;all or nothing&quot;, meaning it expects that 
either all records are encrypted or all records are not encrypted. You turn 
encryption on by passing an encryption key when opening the database.</font></p>
<u>
<p dir="ltr"><font face="Arial">FileDb is thread-safe for multithreading environments, so it can be accessed from 
multiple threads at the same time without worrying about database corruption.</font></u></p>
<p><font face="Arial">FileDb databases can only be opened by a single 
application. Any attempt to open the file when already open will fail.&nbsp; 
This makes sense since its meant for use by a single application at a time 
(FileDb is not meant as a multi-user database, such as SQL Server Express).<br>
&nbsp;</font></p>
<p><b><font color="#0066CC" face="Arial">FileDb Classes</font></b></p>
<p><font face="Arial">The main FileDb classes are: <b>FileDb</b>, <b>Table</b>,
<b>Field</b> and <b>Record</b>. </font> </p>
<dir>
	<b>
	<li><font face="Arial">FileDb</font></b><font face="Arial">: Represents a database file. All database operations are 
	initiated through this class.<br>
&nbsp;</li>
	</font>
	<b>
	<li><font face="Arial">Table</font></b><font face="Arial">: Represents a two 
	dimensional dataset returned from a query. A Table consists of <b>Fields </b>
	and <b>Records</b>.<br>
&nbsp;</li>
	</font>
	<b>
	<li><font face="Arial">Field</font></b><font face="Arial">: Defines the 
	properties of the table column, such as Name and DataType.<br>
&nbsp;</li>
	</font>
	<b>
	<li><font face="Arial">Fields</font></b><font face="Arial">: A List of Field 
	objects.<br>
&nbsp;</font></li>
	<li>
	<font face="Arial">
	<b>
	Record</b>: A list of data objects represents a single row in a Table.&nbsp; 
	Implements IEnumerable and the Data property which is used for DataBinding.<br>
&nbsp;</li>
	</font>
	<b>
	<li><font face="Arial">Records</font></b><font face="Arial">: A List of 
	Record objects.<br>
&nbsp;</li>
	</font>
	<b>
	<li><font face="Arial">FieldValues</font></b><font face="Arial">: A simple 
	Name/Value pair Dictionary. Use this class when adding and updating records.<br>
&nbsp;</li>
	</font>
	<b>
	<li><font face="Arial">FilterExpression</font></b><font face="Arial">: Used 
	to filter records for query, update and delete.<br>
&nbsp;</li>
	</font>
	<b>
	<li><font face="Arial">FilterExpressionGroup</font></b><font face="Arial">: 
	Used to create compound expressions by grouping FilterExpressions and 
	FilterExpressionGroups.<br>
&nbsp;</font></li>
</dir>
<p><b><font color="#0066CC" face="Arial">Database Fields</font></b></p>
<p><font face="Arial">Fields (or Columns) can be of several common types: 
String, Int, UInt, Bool, Byte, Float, Double and DateTime, or can also be an array of any of 
these types.</font></p>
<p><font face="Arial">Int Fields can be AutoIncrementing, and you can optionally 
specify one field to be Primary Key (it must be of type Int or String).</font></p>
<p><font face="Arial">FileDb doesn't support the notion of NULL fields for the 
non-array type. Only array type fields can have NULL values. The non-array field 
values will always have a value, either zero or empty.</font></p>
<p><font color="#0066CC" face="Arial"><b>FileDb Records</b></font></p>
<p><font face="Arial">FileDb supports two methods of data retrieval.&nbsp; You can say the 
&quot;default&quot; way is with the built-in Record and Records classes.&nbsp; Think of 
Record as the .NET DataRow class, and think of Table as a DataTable.&nbsp; Table 
is a list of Records, and a Record holds the actual values. You access Field 
values using indexing just as you would a DataRow, like this:</font></p>
						<blockquote>
							<font FACE="Courier New">
							<table border="0" width="100%" id="table25" bgcolor="#FBEDBB" cellpadding="10">
								<tr>
									<td>
									<font face="Courier New" size="2">FileDb employeesDb = new FileDb();<br>
									employeesDb.Open( Employees.fdb&quot; );<br>
									<br>
									Table employees = employeesDb.SelectAllRecords();<br>
									Record record = 
									employees[0];<br>
									int id = (int) record[&quot;EmployeeId&quot;];<br>
									// or<br>
									id 
									= (int) record[0];</font></td>
								</tr>
							</table>
</font>
						</blockquote>
						<p><font face="Arial">To use a Table with LINQ, you do this:</font></p>
						<blockquote>
							<font FACE="Courier New">
							<table border="0" width="100%" id="table26" bgcolor="#FBEDBB" cellpadding="10">
								<tr>
									<td>
									<font FACE="Courier New" size="2">var recs = from e in
									employees<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; where (string) 
									e[&quot;FirstName&quot;] == &quot;John&quot;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select e;</font></td>
								</tr>
							</table>
</font>
						</blockquote>
						<p><font face="Arial">Notice we have to cast the record value to a string.&nbsp; 
						This is because, just like with the DataRow, Record 
						values are all type object.</font></p>
						<p><font color="#0066CC" face="Arial"><b>Records and Custom Objects</b></font></p>
						<p><font face="Arial">Records are great because they require no additional 
						programming and they work with LINQ, albeit with some 
						casting.&nbsp; But you can use your own custom classes 
						if you want because FileDb has template (generic) 
						overloads for each of the SelectRecords methods.&nbsp; 
						You only need to create a class with public properties 
						which match the names of the fields you want to use.&nbsp; 
						Here&#39;s an example using the Employees table.</font></p>
						<blockquote>
							<font FACE="Courier New">
							<table border="0" width="100%" id="table27" bgcolor="#FBEDBB" cellpadding="10">
								<tr>
									<td>
									<font FACE="Courier New" size="2">public class Employee<br>
									{<br>
&nbsp;&nbsp;&nbsp; public int EmployeeID { get; set; }<br>
&nbsp;&nbsp;&nbsp; public string LastName { get; set; }<br>
									&nbsp;&nbsp;&nbsp;
									public string 
									FirstName { get; set; }<br>
									&nbsp;&nbsp;&nbsp;
									public string Title { 
									get; set; }<br>
									&nbsp;&nbsp;&nbsp;
									public string 
									TitleOfCourtesy { get; set; }<br>
									&nbsp;&nbsp;&nbsp;
									public DateTime 
									BirthDate { get; set; }<br>
									&nbsp;&nbsp;&nbsp;
									public DateTime 
									HireDate { get; set; }<br>
									&nbsp;&nbsp;&nbsp;
									public string Address 
									{ get; set; }<br>
									&nbsp;&nbsp;&nbsp;
									public string City { 
									get; set; }<br>
									&nbsp;&nbsp;&nbsp;
									public string Region { 
									get; set; }<br>
									&nbsp;&nbsp;&nbsp;
									public string 
									PostalCode { get; set; }<br>
									&nbsp;&nbsp;&nbsp;
									public string Country 
									{ get; set; }<br>
									&nbsp;&nbsp;&nbsp;
									public string 
									HomePhone { get; set; }<br>
									&nbsp;&nbsp;&nbsp;
									public string 
									Extension { get; set; }<br>
									&nbsp;&nbsp;&nbsp;
									public Byte[] Photo { 
									get; set; }<br>
									&nbsp;&nbsp;&nbsp;
									public string Notes { 
									get; set; }<br>
									&nbsp;&nbsp;&nbsp;
									public int ReportsTo { 
									get; set; }<br>
									}</font></td>
								</tr>
							</table>
</font>
						</blockquote>
						<p><font face="Arial">The templated SelectRecords versions return a IList&lt;T&gt; 
						where T is your custom type.</font></p>
						<blockquote>
							<font FACE="Courier New">
							<table border="0" width="100%" id="table28" bgcolor="#FBEDBB" cellpadding="10">
								<tr>
									<td>
							<font FACE="Courier New" size="2">
									IList&lt;Employee&gt;
									employees = employeesDb.SelectAllRecords&lt;Employee&gt;();<br>
									Employee employee 
									= employees[0];<br>
									int id = Employee.EmployeeId;<br>
									<br>
									var emps = from e in 
									employees<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; where e.FirstName 
									== &quot;John&quot;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select e;</td>
								</tr>
							</table>
</font>
						</blockquote>
						<p><font face="Arial">As you can see, this is much cleaner code.&nbsp; And 
						its actually more efficient since the Record class has 
						more overhead because its not as simple.</font></p>
						<p><b><font color="#0066CC" face="Arial">Searching and Filtering</font></b></p>
						<p><font face="Arial">FileDb uses FilterExpressions and 
						FilterExpressionGroups to filter records in queries and 
						updates. We use FilterExpressions for simple queries 
						which consist of a single field comparison (field = 
						&#39;value&#39;) and we use FilterExpressionGroups for compound 
						expressions, where multiple expressions and grouping are 
						required. You can add either FilterExpressions or 
						FilterExpressionGroups to a FilterExpressionGroup, thus 
						creating complex expresssions (FileDb processes 
						FilterExpressionGroups recursively).</font></p>
						<p><font face="Arial">You can either create your own manually in code or 
						use the built-in Expression Parser to create them for 
						you. The Expression Parser recognizes standard SQL 
						comparison operators. You can see it used in the 
						examples below. It also recognizes REGEX, which 
						uses Regular Expressions, and CONTAINS which uses <b>
						String.Contains</b>. See the section on 
						Regular Expressions below for more info. Field names 
						prefixed with ~ specifies no-case comparison (for 
						strings only).</font></p>
<p><font face="Arial">Each time you use () around an expression, a new 
FilterExpressionGroup will be created. The inner-most expressions are evaluated 
first, just as in SQL.</font></p>
<b>
<p><font color="#333333" face="Arial">Example 1: Create a FilterExpression</font></p>
</b>
						<blockquote>
							<font FACE="Courier New">
							<table border="0" width="100%" id="table29" bgcolor="#FBEDBB" cellpadding="10">
								<tr>
									<td>
									<font size="2" FACE="Courier New">// build an expression manually<br>
	FilterExpression searchExp = new FilterExpression( &quot;LastName&quot;, &quot;Peacock&quot;, 
	Equality.Equal );<br>
									<br>
									// build the same expression using the 
									parser<br>
	searchExp = FilterExpression.Parse( &quot;LastName = 'Peacock'&quot; ); <br>
									Table table = employeesDb.SelectRecords( 
									searchExp, 
									new string[] { &quot;ID&quot;, &quot;LastName&quot; } );<br>
									<br>
									// Or you can simply pass the string filter 
									directly - a FilterExpression will be 
									created in the same way as above<br>
									<br>
									table = employeesDb.SelectRecords( &quot;LastName 
									= &#39;Peacock&#39;&quot;, new string[] { &quot;ID&quot;, &quot;LastName&quot; 
									} );<br>
									<br>
									foreach( Record record in table )<br>
									{<br>
&nbsp;&nbsp;&nbsp; foreach( object value in record )<br>
&nbsp;&nbsp;&nbsp; {<br>
									&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
									Debug.WriteLine( value );<br>
									&nbsp;&nbsp;&nbsp; 
									}<br>
									}</font></td>
								</tr>
							</table>
</font>
						</blockquote>
<b>
<p><font color="#333333" face="Arial"><br>
Example 2: Create a FilterExpressionGroup</font></p>
</b>
<p><font face="Arial">This example creates two identical FilterExpressionGroups, 
one using the Expression Parser and the other with code.</font></p>
<blockquote>
<font FACE="Courier New">
	<table border="0" width="100%" id="table30" bgcolor="#FBEDBB" cellpadding="10">
		<tr>
			<td><font size="2" FACE="Courier New">// For string fields there are 
			2 ways to specify </font><font size="2" FACE="Courier New">no-case 
			comparisons: you can prefix fieldnames with ~ or you can use ~= as 
			demonstrated below<br>
			// The first form is needed when using the IN operator, eg.<br>
			FilterExpressionGroup filterExpGrp = 
	FilterExpressionGroup.Parse( &quot;(FirstName ~= 'andrew' OR ~FirstName = 'nancy') 
	AND LastName = 'Fuller'&quot; );<br>
	Table table = employeesDb.SelectRecords( filterExpGrp );<br>
	<br>
	// equivalent building it manually<br>
	var fname1Exp = new FilterExpression( &quot;FirstName&quot;, &quot;andrew&quot;, Equality.Equal, 
	MatchType.IgnoreCase );<br>
	var fname2Exp = new FilterExpression( &quot;FirstName&quot;, &quot;nancy&quot;, Equality.Equal, 
	MatchType.IgnoreCase );<br>
	var lnameExp = new FilterExpression( &quot;LastName&quot;, &quot;Fuller&quot;, Equality.Equal ); 
			// this constructor defaults to MatchType.UseCase<br>
	var fnamesGrp = new FilterExpressionGroup();<br>
	fnamesGrp.Add( BoolOp.Or, fname1Exp );<br>
	fnamesGrp.Add( BoolOp.Or, fname2Exp );<br>
	var allNamesGrp = new FilterExpressionGroup();<br>
	allNamesGrp.Add( BoolOp.And, lnameExp );<br>
	allNamesGrp.Add( BoolOp.And, fnamesGrp );<br>
	<br>
	table = employeesDb.SelectRecords( allNamesGrp );<br>
			<br>
			// or just pass the filter string directly<br>
			<br>
			table = employeesDb.SelectRecords( &quot;(FirstName ~= 'andrew' OR ~FirstName = 'nancy') 
	AND LastName = &#39;Fuller&#39;&quot; );<br>
			&nbsp;</font></td>
		</tr>
	</table>
	</font>
</blockquote>
<p><font face="Arial"><br>
FileDb supports these comparison operators:</font></p>
						<font face="Arial" size="2">
						<font face="Courier New">
<blockquote>
	<table border="0" id="table31" style="border-collapse: collapse" bgcolor="#FBEDBB" cellpadding="7">
		<tr>
						<font face="Courier New" size="2">
			<td><b>=</b></td>
			</font><font face="Arial" size="2">
			<td width="18">&nbsp;</td>
			<font face="Courier New">
			<td><font face="Arial">Equality</font></td>
			</font></font>
		</tr>
		<tr>
			<td>~<b>=</b></td>
			</font><font face="Arial">
			<td width="18">&nbsp;</td>
			<font face="Courier New">
			<td>No-case equality - strings only</td>
		</tr>
		<tr>
			<td><font face="Courier New"><b>&lt;&gt;</b></font></td>
			</font><font face="Arial">
			<td width="18">&nbsp;</td>
			<font face="Courier New">
			<td><font face="Arial">Not Equal</font></td>
		</tr>
		<tr>
			<td><font face="Courier New"><b>!=</b></font></td>
			</font><font face="Arial">
			<td width="18">&nbsp;</td>
			<font face="Courier New">
			<td><font face="Arial">Not Equal (same as &lt;&gt;)</font></td>
		</tr>
		<tr>
			<td><font face="Courier New"><b>&gt;=</b></font></td>
			</font><font face="Arial">
			<td width="18">&nbsp;</td>
			<font face="Courier New">
			<td><font face="Arial">Greater than or Equal</font></td>
		</tr>
		<tr>
			<td><font face="Courier New"><b>&lt;=</b></font></td>
			</font><font face="Arial">
			<td width="18">&nbsp;</td>
			<font face="Courier New">
			<td><font face="Arial">Less than or Equal</font></td>
		</tr>
						</font>
						<font face="Courier New" size="2">
		<tr>
			<td><b><font face="Courier New">REGEX</font></b></td>
						</font>
			</font>
						<font face="Arial" size="2">
						<font face="Arial">
			<td width="18">&nbsp;</td>
			<td><font face="Arial">Use Regular Expression</font></td>
		</tr>
		<tr>
			<font face="Arial" size="2">
			<td><b><font face="Courier New">CONTAINS</font></b></td>
			<font face="Arial">
			<td width="18">&nbsp;</td>
			<td><font face="Arial">Use the .NET String's Contains method</font></td>
						</font>
						</font>
		</tr>
		<tr>
			<td><b><font face="Courier New">IN</font></b></td>
			<td width="18">&nbsp;</td>
			<td><font face="Arial">Creates a HashSet of values to use like SQL 
			IN operator</font></td>
		</tr>
		<tr>
			<font face="Arial" size="2">
			<td><b><font face="Courier New">NOT</font></b></td>
			<font face="Arial">
			<td width="18">&nbsp;</td>
			<td><font face="Arial">Logical Negation, e.g NOT CONTAINS</font></td>
						</font>
						</font>
		</tr>
	</table>
</blockquote>
						</font>
						</font>
</font></font></font></font></font>
						<font face="Arial" size="2">
<p>&nbsp;</p>
						</font>
<p><b><font face="Arial" color="#0066CC">REGEX - </font>
<font color="#0066CC" face="Arial" size="3">Regular Expressions in searches and filtering</font></b></p>
<p><font face="Arial" size="3">FileDb supports using Regular Expressions. You can use any RegEx supported by 
.NET. The Expression Parser supports MatchType.RegEx using the REGEX operator.&nbsp; 
Internally, FileDb uses FilterExpressions to evaluate fields.&nbsp; You don&#39;t 
need to use them because you can pass in filter strings and they&#39;ll be parsed 
into FilterExpressions/FilterExpressionGroups for you.&nbsp; This is just to 
show you how can create them manually if you want to.&nbsp; In 
the example below, both FilterExpressionGroups are identical.</font></p>
						<font FACE="Courier New" size="2">
<blockquote>
<font FACE="Courier New">
	<table border="0" id="table32" bgcolor="#FBEDBB" cellpadding="10">
		<tr>
			<td><font size="2" FACE="Courier New">// Using the Expression Parser<br>
	<br>
			// You can use brackets around fieldnames if there are spaces in the 
			name<br>
	FilterExpressionGroup filterExpGrp = FilterExpressionGroup.Parse( &quot;(~FirstName = 'steven' OR [FirstName] 
			REGEX 'NANCY') AND LastName = 'Fuller'&quot; );<br>
	Table table = employeesDb.SelectRecords( filterExpGrp );<br>
			<br>
	// we can manually build the same FilterExpressionGroup<br>
	var fname1Exp = FilterExpression.Parse( &quot;~FirstName = steven&quot; );<br>
	var fname2Exp = new FilterExpression( &quot;FirstName&quot;, &quot;NANCY&quot;, Equality.Regex );<br>
	var lnameExp = new FilterExpression( &quot;LastName&quot;, &quot;Fuller&quot;, Equality.Equal );<br>
	var fnamesGrp = new FilterExpressionGroup();<br>
	fnamesGrp.Add( BoolOp.Or, fname1Exp );<br>
	fnamesGrp.Add( BoolOp.Or, fname2Exp );<br>
	var allNamesGrp = new FilterExpressionGroup();<br>
	allNamesGrp.Add( BoolOp.And, lnameExp );<br>
	allNamesGrp.Add( BoolOp.And, fnamesGrp );<br>
			<br>
	table = employeesDb.SelectRecords( allNamesGrp );</font></td>
		</tr>
	</table>
</font>
</blockquote>
</font>
						<font face="Arial" size="2">
<p>&nbsp;</p>
						</font>
<p><b><font color="#0066CC" face="Arial" size="3">Using CONTAINS in searches and filtering</font></b></p>
<p><font face="Arial" size="3">FileDb supports using Regular Expressions. You can use any RegEx supported by 
.NET. The Expression Parser supports MatchType.RegEx using the REGEX operator.&nbsp; 
Internally, FileDb uses FilterExpressions to evaluate fields.&nbsp; You don&#39;t 
need to use them because you can pass in filter strings and they&#39;ll be parsed 
into FilterExpressions/FilterExpressionGroups for you.&nbsp; This is just to 
show you how can create them manually if you want to.&nbsp; In 
the example below, both FilterExpressionGroups are identical.</font></p>
						<font FACE="Courier New" size="2">
<blockquote>
<font FACE="Courier New">
	<table border="0" id="table42" bgcolor="#FBEDBB" cellpadding="10">
		<tr>
			<td><font size="2" FACE="Courier New">// You can use brackets around fieldnames if there are spaces in the 
			name<br>
	FilterExpressionGroup filterExpGrp = FilterExpressionGroup.Parse( &quot;(~FirstName = 'steven' OR [FirstName] 
			CONTAINS 'NANC') AND LastName = 'Fuller'&quot; );<br>
	Table table = employeesDb.SelectRecords( filterExpGrp );<br>
			<br>
	// we can manually build the same FilterExpressionGroup<br>
	var fname1Exp = FilterExpression.Parse( &quot;~FirstName = steven&quot; );<br>
	var fname2Exp = new FilterExpression( &quot;FirstName&quot;, &quot;NANCY&quot;, Equality.Contains );<br>
	var lnameExp = new FilterExpression( &quot;LastName&quot;, &quot;Fuller&quot;, Equality.Equal );<br>
	var fnamesGrp = new FilterExpressionGroup();<br>
	fnamesGrp.Add( BoolOp.Or, fname1Exp );<br>
	fnamesGrp.Add( BoolOp.Or, fname2Exp );<br>
	var allNamesGrp = new FilterExpressionGroup();<br>
	allNamesGrp.Add( BoolOp.And, lnameExp );<br>
	allNamesGrp.Add( BoolOp.And, fnamesGrp );<br>
			<br>
	table = employeesDb.SelectRecords( allNamesGrp );</font></td>
		</tr>
	</table>
</font>
</blockquote>
</font>
<p>&nbsp;</p>
<p><b><font color="#0066CC" face="Arial" size="3">Sort Ordering</font></b></p>
<p><font face="Arial" size="3">Query methods allow for sorting the results by fields. To 
get a reverse sort, prefix the sort field list with !. To get a no-case sort, 
prefix with ~. To get both reverse and no-case sort, use both ! and ~.</font></p>
<p><font face="Arial" size="3">Example:</font></p>
<blockquote>
<font FACE="Courier New" size="2">
<table border="0" id="table33" bgcolor="#FBEDBB" cellpadding="10">
	<tr>
		<td>
<font FACE="Courier New" size="2">
		Table table = employeesDb.SelectAllRecords( new string[] { &quot;ID&quot;, &quot;Firstname&quot;, &quot;LastName&quot;, 
	&quot;Age&quot; }, false, new string[] { &quot;~LastName&quot;, &quot;~FirstName&quot;, &quot;!Age&quot; } );</font></td>
	</tr>
</table>
</font>
						</blockquote>
<p><font color="#0066CC" face="Arial" size="3"><b>Selecting a Table from a Table</b></font></p>
<p><font face="Arial" size="3">Another very powerful feature of FileDb is the ability to select a Table from 
another Table.&nbsp; This would allow you to be able to select data from a Table 
after the database file has been closed, for example.</font></p>
<p><font face="Arial" size="3">Example:</font></p>
<blockquote>
<font FACE="Courier New" size="2">
<table border="0" id="table34" bgcolor="#FBEDBB" cellpadding="10">
	<tr>
		<td>
<font FACE="Courier New" size="2">
		customersDb.Open( path + &quot;Customers.fdb&quot; );<br>
<br>
// select all fields and records from the database table<br>
Table customers = customersDb.SelectAllRecords();<br>
<br>
Table subCusts = customers.SelectRecords( &quot;CustomerID &lt;&gt; &#39;ALFKI&#39;&quot;,<br>
new string[] { &quot;CustomerID&quot;, &quot;CompanyName&quot;, &quot;City&quot; }, new string[] { &quot;~City&quot;, &quot;~CompanyName&quot; 
} );</font></td>
	</tr>
</table>
</font>
						</blockquote>
<p><b><font color="#0066CC" face="Arial" size="3">Encryption</font></b></p>
<p><font face="Arial" size="3">Using encryption with FileDb is simple. You only need to 
specify a string key when you open the database. After that everything is 
automatic. The only caveat is you must set a key before you add any records. 
Once a single record has been added without a key set you cannot later add 
records with a key. Its all or nothing. Likewise, you cannot add records with 
encryption and later add records without.&nbsp; You must set the encryption key 
each time you add any records.</font></p>
<p><b><font color="#0066CC" face="Arial" size="3">Persisting Tables</font></b></p>
<p><font face="Arial" size="3">You can easily save a Table as a new database using 
Table.SaveToDb.&nbsp; This method creates a new database file using the Fields 
in the Table then populates it using the Records in the Table.&nbsp; For 
example, you can select subsets of your data, save it as a new database and send 
it over the Internet.</font></p>
						<blockquote>
<font FACE="Courier New">
							<table border="0" id="table35" bgcolor="#FBEDBB" cellpadding="10">
								<tr>
									<td><font FACE="Courier New" size="2">Table table = employeesDb.SelectAllRecords( new string[] { &quot;ID&quot;, &quot;Firstname&quot;, &quot;LastName&quot; 
									} );<br>
	table.SaveToDb( &quot;Names.fdb&quot; );</font></td>
								</tr>
							</table>
</font>
						</blockquote>
						<p><font face="Arial" size="3">You can also save a Table to a database from the 
						FileDb Explorer. Just right-click on the Grid to show 
						the context menu and select the &quot;Create database from 
						Table...&quot; menu item.<br>
&nbsp;</font></p>
						<p><font color="#0066CC" face="Arial" size="3"><b>Using LINQ to Objects with FileDb</b></font></p>
						<p><font face="Arial" size="3">Microsoft has done an amazing job with LINQ.&nbsp; 
						They have invested a huge amount of time, effort and $ 
						in this technology which allows you to query just about 
						any kind of data in a SQL-like way.&nbsp; We use LINQ 
						with FileDb to join Tables as we would using SQL.&nbsp; 
						The difference is that instead of doing it all in a 
						single step with SQL, we must do it in two steps.&nbsp; 
						First we select the data Tables from the database files 
						then we use LINQ to join them together.</font></p>
						<p><font face="Arial" size="3">LINQ to Objects produces a list of anonymous types as 
						its result set.&nbsp; This is good because we get 
						strongly typed data objects which we can easily use in WPF/Silverlight apps.</font></p>
						<p><font face="Arial" size="3">Here is an example of doing a simple select using 
						LINQ:</font></p>
						<blockquote>
<font FACE="Courier New">
							<table border="0" id="table36" bgcolor="#FBEDBB" cellpadding="10">
								<tr>
									<td><font face="Courier New" size="2">// 
									Using the IN operator.&nbsp; Notice the ~ 
									prefix on the LastName field. This is how
									<br>
									// you can specify case insensitive searches<br>
									<br>
									Table 
									employees = employeesDb.SelectRecords( &quot;~LastName 
									IN (&#39;Fuller&#39;, &#39;Peacock&#39;)&quot; );<br>
									<br>
									var query =
									from record in employees<br>
									select new<br>
									{<br>
&nbsp;&nbsp;&nbsp; ID = record[&quot;EmployeeId&quot;],<br>
&nbsp;&nbsp;&nbsp; Name = record[&quot;FirstName&quot;] + &quot; &quot; + record[&quot;LastName&quot;],<br>
&nbsp;&nbsp;&nbsp; Title = record[&quot;Title&quot;]<br>
									};<br>
									<br>
									foreach( var rec in query )<br>
									{<br>
&nbsp;&nbsp;&nbsp; Debug.WriteLine( rec.ToString() );<br>
									}</font></td>
								</tr>
							</table>
</font>
						<p><font face="Arial" size="3">The only thing LINQ did for us in this example was 
						gave us a typed list of anonymous objects.&nbsp; Here&#39;s 
						the same thing but with custom objects:</font></p>
<font FACE="Courier New">
							<table border="0" id="table37" bgcolor="#FBEDBB" cellpadding="10">
								<tr>
									<td><font size="2">IList&lt;Employee&gt;</font><font face="Courier New" size="2"> employees 
									= employeesDb.SelectRecords&lt;Employee&gt;( 
									&quot;~LastName 
									IN (&#39;Fuller&#39;, &#39;Peacock&#39;)&quot; );<br>
									<br>
									var query =<br>
									from e in employees<br>
									select e;<br>
									<br>
									foreach( var emp in query )<br>
									{<br>
&nbsp;&nbsp;&nbsp; Debug.WriteLine( emp.ToString() );<br>
									}</font></td>
								</tr>
							</table>
</font>
						</blockquote>
<p dir="ltr"><font face="Arial" size="3">Now lets tap into LINQ&#39;s real power to join tables together 
like a SQL inner join.&nbsp; Notice in the following example we use the </font>
<font face="Courier New" size="2">FilterExpression.CreateInExpressionFromTable</font><font face="Arial"><font size="3">
method.&nbsp; We do this to get only the records we are going to need with LINQ.&nbsp; 
So using FileDb with LINQ is a two step process.&nbsp; You first select the 
records you will need then use them in the LINQ query.&nbsp; If your database 
files are large, you can filter the records like this.&nbsp; Otherwise you can 
just select all records.</font></p>
						<blockquote>
<font FACE="Courier New">
							<table border="0" id="table38" bgcolor="#FBEDBB" cellpadding="10">
								<tr>
									<td><font face="Courier New" size="2">FileDb customersDb = new FileDb(),<br>
									ordersDb = new FileDb(),<br>
									orderDetailsDb = new FileDb(),<br>
									productsDb = new FileDb();<br>
									<br>
									customersDb.Open( &quot;Customers.fdb&quot; );<br>
									ordersDb.Open( &quot;Orders.fdb&quot; );<br>
									orderDetailsDb.Open( &quot;OrderDetails.fdb&quot; );<br>
									productsDb.Open( &quot;Products.fdb&quot; );<br>
									<br>
									// get our target Customer records<br>
									// Note that we should select only fields we 
									need from each table, but to keep the code<br>
									// simple for this example we just pass in null for the field 
									list<br>
									<br>
									FilterExpression filterExp = 
									FilterExpression.Parse( &quot;CustomerID IN( &#39;ALFKI&#39;, 
									&#39;BONAP&#39; )&quot; );<br>
									FileDbNs.Table customers = 
									customersDb.SelectRecords( filterExp );<br>
									<br>
									// now get only Order records for the target 
									Customer records<br>
									// CreateInExpressionFromTable will create 
									an IN FilterExpression, which uses a HashSet
									<br>
									// for high efficiency when filtering 
									records<br>
&nbsp;<br>
									filterExp = 
									FilterExpression.CreateInExpressionFromTable( 
									&quot;CustomerID&quot;, customers, &quot;CustomerID&quot; );<br>
									FileDbNs.Table orders = 
									ordersDb.SelectRecords( filterExp );<br>
									<br>
									// now get only OrderDetails records for the 
									target Order records<br>
									<br>
									filterExp = 
									FilterExpression.CreateInExpressionFromTable( 
									&quot;OrderID&quot;, orders, &quot;OrderID&quot; );<br>
									FileDbNs.Table orderDetails = 
									orderDetailsDb.SelectRecords( filterExp );<br>
									<br>
									// now get only Product records for the 
									target OrderDetails records<br>
									<br>
									filterExp = 
									FilterExpression.CreateInExpressionFromTable( 
									&quot;ProductID&quot;, orderDetails, &quot;ProductID&quot; );<br>
									FileDbNs.Table products = 
									productsDb.SelectRecords( filterExp );<br>
									<br>
									// now we&#39;re ready to do the join<br>
									<br>
									var query =<br>
&nbsp;&nbsp;&nbsp; from custRec in customers<br>
&nbsp;&nbsp;&nbsp; join orderRec in orders on custRec[&quot;CustomerID&quot;] 
									equals orderRec[&quot;CustomerID&quot;]<br>
&nbsp;&nbsp;&nbsp; join orderDetailRec in orderDetails on 
									orderRec[&quot;OrderID&quot;] equals 
									orderDetailRec[&quot;OrderID&quot;]<br>
&nbsp;&nbsp;&nbsp; join productRec in products on 
									orderDetailRec[&quot;ProductID&quot;] equals 
									productRec[&quot;ProductID&quot;]<br>
&nbsp;&nbsp;&nbsp; select new<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ID = custRec[&quot;CustomerID&quot;],<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CompanyName = custRec[&quot;CompanyName&quot;],<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OrderID = orderRec[&quot;OrderID&quot;],<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OrderDate = orderRec[&quot;OrderDate&quot;],<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ProductName = productRec[&quot;ProductName&quot;],<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UnitPrice = orderDetailRec[&quot;UnitPrice&quot;],<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Quantity = orderDetailRec[&quot;Quantity&quot;]<br>
&nbsp;&nbsp;&nbsp; };<br>
									<br>
									foreach( var rec in query )<br>
									{<br>
&nbsp;&nbsp;&nbsp; Debug.WriteLine( rec.ToString() );<br>
									}</font></td>
								</tr>
							</table>
</font>
						<p><font face="Arial" size="3">Here&#39;s the same thing again using custom objects:</font></p>
<font FACE="Courier New">
							<table border="0" id="table39" bgcolor="#FBEDBB" cellpadding="10">
								<tr>
									<td><font face="Courier New" size="2">// get our target Customer records<br>
									<br>
									FilterExpression filterExp = 
									FilterExpression.Parse( &quot;CustomerID IN( &#39;ALFKI&#39;, 
									&#39;BONAP&#39; )&quot; );<br>
									IList&lt;Customer&gt; customers = 
									customersDb.SelectRecords&lt;Customer&gt;( filterExp );<br>
&nbsp;<br>
									filterExp = 
									FilterExpression.CreateInExpressionFromTable&lt;Customer&gt;( 
									&quot;CustomerID&quot;, customers, &quot;CustomerID&quot; );<br>
									IList&lt;Order&gt; orders = 
									ordersDb.SelectRecords&lt;Order&gt;( filterExp );<br>
									<br>
									// now get only OrderDetails records for the 
									target Order records<br>
									<br>
									filterExp = 
									FilterExpression.CreateInExpressionFromTable&lt;Order&gt;( 
									&quot;OrderID&quot;, orders, &quot;OrderID&quot; );<br>
									IList&lt;OrderDetail&gt; orderDetails = 
									orderDetailsDb.SelectRecords&lt;OrderDetail&gt;( filterExp );<br>
									<br>
									// now get only Product records for the 
									target OrderDetails records<br>
									<br>
									filterExp = 
									FilterExpression.CreateInExpressionFromTable&lt;OrderDetail&gt;( 
									&quot;ProductID&quot;, orderDetails, &quot;ProductID&quot; );<br>
									IList&lt;Product&gt; products = 
									productsDb.SelectRecords&lt;Product&gt;(( filterExp );<br>
									<br>
									// now we&#39;re ready to do the join<br>
									<br>
									var query =<br>
&nbsp;&nbsp;&nbsp; from custRec in customers<br>
&nbsp;&nbsp;&nbsp; join orderRec in orders on custRec.CustomerID 
									equals orderRec.CustomerID<br>
&nbsp;&nbsp;&nbsp; join orderDetailRec in orderDetails on 
									orderRec.OrderID equals orderDetailRec.OrderID<br>
&nbsp;&nbsp;&nbsp; join productRec in products on 
									orderDetailRec.ProductID equals productRec.ProductID<br>
&nbsp;&nbsp;&nbsp; select new<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ID = custRec.CustomerID,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CompanyName = custRec.CompanyName,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OrderID = orderRec.OrderID,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OrderDate = orderRec.OrderDate,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ProductName = productRec.ProductName,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UnitPrice = orderDetailRec.UnitPrice,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Quantity = orderDetailRec.Quantity<br>
&nbsp;&nbsp;&nbsp; };<br>
									<br>
									foreach( var rec in query )<br>
									{<br>
&nbsp;&nbsp;&nbsp; Debug.WriteLine( rec.ToString() );<br>
									}</font></td>
								</tr>
							</table>
						</blockquote>
<p>&nbsp;</p>
</font>
						<p><b>
						<font color="#0066CC" face="Arial" size="3">Creating a Database</font></p>
</b>
<p><font face="Arial" size="3">You create your database programmatically by defining 
Fields and adding them to an array then calling FileDb.Create, similar to below. 
Notice we set the ID field to be AutoIncrementing and PrimaryKey. This code 
creates a database with every type of field.</font></p>
<font FACE="Courier New">
<blockquote>
	<table border="0" width="100%" id="table40" bgcolor="#FBEDBB" cellpadding="10">
		<tr>
			<td><font size="2" FACE="Courier New">Field field;<br>
	var fieldLst = new List&lt;Field&gt;( 20 );<br>
	field = new Field( &quot;ID&quot;, DataType.Int );<br>
	field.AutoIncStart = 0;<br>
	field.IsPrimaryKey = true;<br>
	fields.Add( field );<br>
	field = new Field( &quot;FirstName&quot;, DataType.String );<br>
	fields.Add( field );<br>
	field = new Field( &quot;LastName&quot;, DataType.String );<br>
	fields.Add( field );<br>
	field = new Field( &quot;BirthDate&quot;, DataType.DateTime );<br>
	fields.Add( field );<br>
	field = new Field( &quot;IsCitizen&quot;, DataType.Bool );<br>
	fields.Add( field );<br>
	field = new Field( &quot;DoubleField&quot;, DataType.Double );<br>
	fields.Add( field );<br>
	field = new Field( &quot;ByteField&quot;, DataType.Byte );<br>
	fields.Add( field );<br>
	<br>
	// array types<br>
	field = new Field( &quot;StringArrayField&quot;, DataType.String );<br>
	field.IsArray = true;<br>
	fields.Add( field );<br>
	field = new Field( &quot;ByteArrayField&quot;, DataType.Byte );<br>
	field.IsArray = true;<br>
	fields.Add( field );<br>
	field = new Field( &quot;IntArrayField&quot;, DataType.Int );<br>
	field.IsArray = true;<br>
	fields.Add( field );<br>
	field = new Field( &quot;DoubleArrayField&quot;, DataType.Double );<br>
	field.IsArray = true;<br>
	fields.Add( field );<br>
	field = new Field( &quot;DateTimeArrayField&quot;, DataType.DateTime );<br>
	field.IsArray = true;<br>
	fields.Add( field );<br>
	field = new Field( &quot;BoolArray&quot;, DataType.Bool );<br>
	field.IsArray = true;<br>
	fields.Add( field );</font><font size="2"><br>
			<br>
			var myDb = new FileDb();</font><font size="2" FACE="Courier New"><br>
			myDb.Create( &quot;MyDatabase.fdb&quot;, fieldLst.ToArray() );</font></td>
		</tr>
	</table>
</blockquote>
</font>
<p><b><font color="#0066CC" face="Arial" size="3"><br>
Adding Records</font></b></p>
<p><font face="Arial" size="3">You add records to a database by creating a FieldValues 
object and adding field values. You do not need to represent every field of the 
database. Fields that are missing will be initialized to the default value (zero 
for numeric types, DateTime.MinValue, 
empty for String and NULL for array types).</font></p>
<font FACE="Courier New">
						<blockquote>
							<table border="0" width="100%" id="table41" bgcolor="#FBEDBB" cellpadding="10">
								<tr>
									<td>
<font size="2" FACE="Courier New">var record = new FieldValues();<br>
	record.Add( &quot;FirstName&quot;, &quot;Nancy&quot; );<br>
	record.Add( &quot;LastName&quot;, &quot;Davolio&quot; );<br>
	record.Add( &quot;BirthDate&quot;, new DateTime( 1968, 12, 8 ) );<br>
	record.Add( &quot;IsCitizen&quot;, true );<br>
	record.Add( &quot;Double&quot;, 1.23 );<br>
	record.Add( &quot;Byte&quot;, 1 );<br>
	record.Add( &quot;StringArray&quot;, new string[] { &quot;s1&quot;, &quot;s2&quot;, &quot;s3&quot; } );<br>
	record.Add( &quot;ByteArray&quot;, new Byte[] { 1, 2, 3, 4 } );<br>
	record.Add( &quot;IntArray&quot;, new int[] { 100, 200, 300, 400 } );<br>
	record.Add( &quot;DoubleArray&quot;, new double[] { 1.2, 2.4, 3.6, 4.8 } );<br>
	record.Add( &quot;DateTimeArray&quot;, new DateTime[] { DateTime.Now, DateTime.Now, 
	DateTime.Now, DateTime.Now } );<br>
	record.Add( &quot;BoolArray&quot;, new bool[] { true, false, true, false } );<br>
<br>
	myDb.AddRecord( record );</font></td>
								</tr>
							</table>
						</blockquote>
						<p>&nbsp;</p>
</font>
						
</body>

</html>